package dao;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class BaseSql<T> {
	private Class<T> entity;
	private String table_name;
	private Connection conn;

	@SuppressWarnings("unchecked")
	public BaseSql() {
		// TODO Auto-generated constructor stub
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
	    //Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
	    //getClass().getGenericSuperclass()返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type
		entity = (Class<T>) type.getActualTypeArguments()[0];
		System.out.println(entity+"1");
		 //getActualTypeArguments获取参数化类型的数组，泛型可能有多个
		 //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
		table_name = entity.getSimpleName();
		System.out.println(table_name+"2");
		conn = DBUtil.getConnection();
	}

	public void insert(T o) {
		StringBuffer sql = new StringBuffer("insert into " + table_name + "(");
		Field[] fields = entity.getDeclaredFields();
		System.out.println(fields);
		for (int i = 1; i < fields.length; i++) {
			sql.append(fields[i].getName());
			if (i < fields.length - 1)
				sql.append(",");
			else
				sql.append(") values(?,?)");
		}
		System.out.println(sql);
		try {
			PreparedStatement pstm = conn.prepareStatement(sql.toString());
			for (int i = 1; i < fields.length; i++) {
				fields[i].setAccessible(true);//AccessibleTest类中的成员变量为private,故必须进行此操作
				Object val = fields[i].get(o);
				pstm.setObject(i, val);
			}
			pstm.executeUpdate();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public List<T> select() {
		List<T> list = new ArrayList<>();
		String sql = "select * from " + table_name;
		System.out.println(sql);
		Field[] fields = entity.getDeclaredFields();
		try {
			Statement stm = conn.createStatement();
			ResultSet rs = stm.executeQuery(sql);
			while (rs.next()) {
				T all = entity.newInstance();
				for (int i = 0; i < fields.length; i++) {
					fields[i].setAccessible(true);
					Object selvals = rs.getObject(i + 1);					
					fields[i].set(all, selvals);
					System.out.println(selvals+all.getClass().getName()+selvals.getClass().getName());
				}
				list.add(all);
				

			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public T getOne(Integer id) {
		StringBuffer sql=new StringBuffer("select * from "+table_name+" where ");
		
		Field[] fields = entity.getDeclaredFields();
		sql.append(fields[0].getName()+"="+id);
		System.out.println(sql);
		try {
			Statement stm = conn.createStatement();
			ResultSet rs = stm.executeQuery(sql.toString());
			rs.next();

			T one = entity.newInstance();
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				Object selval = rs.getObject(i + 1);
				if (fields[i].getType().getSimpleName().equals("Integer")) {
					BigDecimal bd = (BigDecimal) selval;
					selval = bd.intValue();
				}
				fields[i].set(one, selval);
			}
			return one;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	public void update(T o,Integer id){
		StringBuffer sql=new StringBuffer("update "+table_name+" set ");
		Field[] fields=entity.getDeclaredFields();
		for (int i = 1; i < fields.length; i++) {
			sql.append(fields[i].getName()+"=?");
			if(i<fields.length-1) sql.append(",");
			else sql.append(" where "+fields[0].getName()+"="+id);
		}
		System.out.println(sql);
		try {
			PreparedStatement pstm=conn.prepareStatement(sql.toString());
			for (int i = 1; i < fields.length; i++) {
				fields[i].setAccessible(true);
				Object val=fields[i].get(o);
				pstm.setObject(i, val);
			}
			pstm.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	public List<T> getCourse(String name){
//		String sql="select name from courses where id in(select course_id where major_id in(select id from major()))" ;
		String sql="select name from courses where id in(select course_id from majorcourse where major_id in(select id from major WHERE NAME=?))";
		try {
			PreparedStatement pstm=conn.prepareStatement(sql);
			pstm.setString(1, name);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
	public void delete(Integer id){
		StringBuffer sql=new StringBuffer("delete from "+table_name+" where ");
		Field[] fields=entity.getDeclaredFields();
		sql.append(fields[0].getName()+"="+id);
		System.out.println(sql);
		try {
			Statement stm=conn.createStatement();
			stm.executeQuery(sql.toString());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
